import {
  EventDispatcher,
  Object3D,
  PerspectiveCamera,
  Raycaster,
  Vector2,
} from "three";
const raycaster = new Raycaster();
const point = new Vector2();
class SelectOperate extends EventDispatcher {
  offsetX: number = 0;
  offsetY: number = 0;
  cacheObject: Object3D | null = null;
  constructor() {
    super();
  }
  intersection(
    x: number,
    y: number,
    camera: PerspectiveCamera,
    scene: Object3D,
    width: number = window.innerWidth,
    height: number = window.innerHeight
  ): Array<any> {
    this.offsetX = x;
    this.offsetY = y;
    point.x = (x / width) * 2 - 1;
    point.y = (-y * 2) / height + 1;
    raycaster.setFromCamera(point, camera);
    const intersection: Array<any> = raycaster.intersectObjects(scene.children);
    return intersection;
  }
  handleClick(
    x: number,
    y: number,
    camera: PerspectiveCamera,
    scene: Object3D,
    width: number = window.innerWidth,
    height: number = window.innerHeight
  ) {
    let intersection = this.intersection(x, y, camera, scene, width, height);
    return intersection[0].object;
  }
  handleMouse(
    x: number,
    y: number,
    camera: PerspectiveCamera,
    scene: Object3D,
    width: number = window.innerWidth,
    height: number = window.innerHeight
  ) {
    let object: any;
    let intersection = this.intersection(x, y, camera, scene, width, height);
    if (intersection.length) {
      object = intersection[0].object;
      if (object != this.cacheObject) {
        if (this.cacheObject) {
          //表示离开上一个
          this.dispatchEvent({
            type: "mouseleave",
            data: this.cacheObject,
          });
        }
        //上次元素和本次不同表示重新进入
        this.dispatchEvent({
          type: "mouseenter",
          data: {
            object,
            x,
            y,
          },
        });
      } else if (object == this.cacheObject) {
        //两次相同表示移动
        this.dispatchEvent({
          type: "mousemove",
          data: {
            x,
            y,
          },
        });
      }
      this.cacheObject = object;
    } else {
      if (this.cacheObject) {
        //表示离开上一个
        this.dispatchEvent({
          type: "mouseleave",
          data: this.cacheObject,
        });
      }
      this.cacheObject = null;
    }
    return object;
  }
}
export const DefaultSelectOperate = new SelectOperate();
